home *** CD-ROM | disk | FTP | other *** search
/ Aminet 45 / Aminet 45 (2001)(GTI - Schatztruhe)[!][Oct 2001].iso / Aminet / gfx / x11 / x3270_3_2_16.lha / amiga_src / mkfb.c < prev    next >
C/C++ Source or Header  |  2009-02-27  |  9KB  |  444 lines

  1. /*
  2.  * Copyright 1995, 1996, 1999, 2000 by Paul Mattes.
  3.  *  Permission to use, copy, modify, and distribute this software and its
  4.  *  documentation for any purpose and without fee is hereby granted,
  5.  *  provided that the above copyright notice appear in all copies and that
  6.  *  both that copyright notice and this permission notice appear in
  7.  *  supporting documentation.
  8.  */
  9.  
  10. /*
  11.  * mkfb.c
  12.  *    Utility to create fallback definitions from a simple #ifdef'd .ad
  13.  *    file
  14.  */
  15.  
  16. #include "parts.h"
  17.  
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <ctype.h>
  21.  
  22. #define BUFSZ    1024        /* input line buffer size */
  23. #define ARRSZ    8192        /* output array size */
  24. #define SSSZ    10        /* maximum nested ifdef */
  25.  
  26. unsigned a_color[ARRSZ];    /* array of color indices */
  27. unsigned l_color[ARRSZ];
  28. unsigned n_color = 0;        /* number of color definitions */
  29.  
  30. unsigned a_mono[ARRSZ];        /* array of mono indices */
  31. unsigned l_mono[ARRSZ];
  32. unsigned n_mono = 0;        /* number of mono definitions */
  33.  
  34. /* ifdef state stack */
  35. #define MODE_COLOR    0x00000001
  36. #define MODE_FT        0x00000002
  37. #define MODE_TRACE    0x00000004
  38. #define MODE_MENUS    0x00000008
  39. #define MODE_ANSI    0x00000010
  40. #define MODE_KEYPAD    0x00000020
  41. #define MODE_APL    0x00000040
  42. #define MODE_PRINTER    0x00000080
  43.  
  44. #define MODEMASK    0x0000007f
  45.  
  46. struct {
  47.     unsigned long ifdefs;
  48.     unsigned long ifndefs;
  49.     unsigned lno;
  50. } ss[SSSZ];
  51. int ssp = 0;
  52.  
  53. struct {
  54.     const char *name;
  55.     unsigned long mask;
  56. } parts[] = {
  57.     { "COLOR", MODE_COLOR },
  58.     { "X3270_FT", MODE_FT },
  59.     { "X3270_TRACE", MODE_TRACE },
  60.     { "X3270_MENUS", MODE_MENUS },
  61.     { "X3270_ANSI", MODE_ANSI },
  62.     { "X3270_KEYPAD", MODE_KEYPAD },
  63.     { "X3270_APL", MODE_APL },
  64.     { "X3270_PRINTER", MODE_PRINTER }
  65. };
  66. #define NPARTS    (sizeof(parts)/sizeof(parts[0]))
  67.  
  68. unsigned long is_defined =
  69.     MODE_COLOR |
  70. #if defined(X3270_FT)
  71.     MODE_FT
  72. #else
  73.     0
  74. #endif
  75. |
  76. #if defined(X3270_TRACE)
  77.     MODE_TRACE
  78. #else
  79.     0
  80. #endif
  81. |
  82. #if defined(X3270_MENUS)
  83.     MODE_MENUS
  84. #else
  85.     0
  86. #endif
  87. |
  88. #if defined(X3270_ANSI)
  89.     MODE_ANSI
  90. #else
  91.     0
  92. #endif
  93. |
  94. #if defined(X3270_KEYPAD)
  95.     MODE_KEYPAD
  96. #else
  97.     0
  98. #endif
  99. |
  100. #if defined(X3270_APL)
  101.     MODE_APL
  102. #else
  103.     0
  104. #endif
  105. |
  106. #if defined(X3270_PRINTER)
  107.     MODE_PRINTER
  108. #else
  109.     0
  110. #endif
  111.     ;
  112. unsigned long is_undefined;
  113.  
  114. char *me;
  115.  
  116. void emit(FILE *t, char c);
  117.  
  118. void
  119. usage(void)
  120. {
  121.     fprintf(stderr, "usage: %s [infile [outfile]]\n", me);
  122.     exit(1);
  123. }
  124.  
  125. int
  126. main(int argc, char *argv[])
  127. {
  128.     char buf[BUFSZ];
  129.     int lno = 0;
  130.     int cc = 0;
  131.     int i;
  132.     int continued = 0;
  133.     const char *filename = "standard input";
  134.     FILE *t, *o;
  135.  
  136.     is_undefined = MODE_COLOR | (~is_defined & MODEMASK);
  137.  
  138.     /* Parse arguments. */
  139.     if ((me = strrchr(argv[0], '/')) != (char *)NULL)
  140.         me++;
  141.     else
  142.         me = argv[0];
  143.     switch (argc) {
  144.         case 1:
  145.         break;
  146.         case 2:
  147.         case 3:
  148.         if (strcmp(argv[1], "-")) {
  149.             if (freopen(argv[1], "r", stdin) == (FILE *)NULL) {
  150.                 perror(argv[1]);
  151.                 exit(1);
  152.             }
  153.             filename = argv[1];
  154.         }
  155.         break;
  156.         default:
  157.         usage();
  158.     }
  159.  
  160.     t = tmpfile();
  161.     if (t == NULL) {
  162.         perror("tmpfile");
  163.         exit(1);
  164.     }
  165.  
  166.     /* Emit the initial boilerplate. */
  167.     fprintf(t, "/* This file was created automatically from %s by mkfb. */\n\n",
  168.         filename);
  169.     fprintf(t, "#if !defined(USE_APP_DEFAULTS) /*[*/\n\n");
  170.     fprintf(t, "#include <stdio.h>\n");
  171.     fprintf(t, "#include <X11/Intrinsic.h>\n\n");
  172.     fprintf(t, "static unsigned char fsd[] = {\n");
  173.  
  174.     /* Scan the file, emitting the fsd array and creating the indices. */
  175.     while (fgets(buf, BUFSZ, stdin) != (char *)NULL) {
  176.         char *s = buf;
  177.         int sl;
  178.         char c;
  179.         int white;
  180.         int i;
  181.         unsigned long ifdefs;
  182.         unsigned long ifndefs;
  183.  
  184.         lno++;
  185.  
  186.         /* Skip leading white space. */
  187.         while (isspace(*s))
  188.             s++;
  189.  
  190.         /* Remove trailing white space. */
  191.         while ((sl = strlen(s)) && isspace(s[sl-1]))
  192.             s[sl-1] = '\0';
  193.  
  194.         if (continued)
  195.             goto emit_text;
  196.  
  197.         /* Skip comments and empty lines. */
  198.         if (!*s || *s == '!')
  199.             continue;
  200.  
  201.         /* Check for simple if[n]defs. */
  202.         if (*s == '#') {
  203.             int ifnd = 1;
  204.  
  205.             if (!strncmp(s, "#ifdef ", 7) ||
  206.                 !(ifnd = strncmp(s, "#ifndef ", 8))) {
  207.                 char *tk;
  208.  
  209.                 if (ssp >= SSSZ) {
  210.                     fprintf(stderr,
  211.                         "%s, line %d: Stack overflow\n",
  212.                         filename, lno);
  213.                     exit(1);
  214.                 }
  215.                 ss[ssp].ifdefs = 0L;
  216.                 ss[ssp].ifndefs = 0L;
  217.                 ss[ssp].lno = lno;
  218.  
  219.                 tk = s + 7 + !ifnd;
  220.                 for (i = 0; i < NPARTS; i++) {
  221.                     if (!strcmp(tk, parts[i].name)) {
  222.                         if (!ifnd)
  223.                             ss[ssp++].ifndefs =
  224.                                 parts[i].mask;
  225.                         else
  226.                             ss[ssp++].ifdefs =
  227.                                 parts[i].mask;
  228.                         break;
  229.                     }
  230.                 }
  231.                 if (i >= NPARTS) {
  232.                     fprintf(stderr,
  233.                         "%s, line %d: Unknown condition\n",
  234.                         filename, lno);
  235.                     exit(1);
  236.                 }
  237.                 continue;
  238.             }
  239.  
  240.             else if (!strcmp(s, "#else")) {
  241.                 unsigned long tmp;
  242.  
  243.                 if (!ssp) {
  244.                     fprintf(stderr,
  245.                         "%s, line %d: Missing #if[n]def\n",
  246.                         filename, lno);
  247.                     exit(1);
  248.                 }
  249.                 tmp = ss[ssp-1].ifdefs;
  250.                 ss[ssp-1].ifdefs = ss[ssp-1].ifndefs;
  251.                 ss[ssp-1].ifndefs = tmp;
  252.             } else if (!strcmp(s, "#endif")) {
  253.                 if (!ssp) {
  254.                     fprintf(stderr,
  255.                         "%s, line %d: Missing #if[n]def\n",
  256.                         filename, lno);
  257.                     exit(1);
  258.                 }
  259.                 ssp--;
  260.             } else {
  261.                 fprintf(stderr,
  262.                     "%s, line %d: Unrecognized # directive\n",
  263.                     filename, lno);
  264.                 exit(1);
  265.             }
  266.             continue;
  267.         }
  268.  
  269.         /* Figure out if there's anything to emit. */
  270.  
  271.         /* First, look for contradictons. */
  272.         ifdefs = 0;
  273.         ifndefs = 0;
  274.         for (i = 0; i < ssp; i++) {
  275.             ifdefs |= ss[i].ifdefs;
  276.             ifndefs |= ss[i].ifndefs;
  277.         }
  278.         if (ifdefs & ifndefs) {
  279. #if 0
  280.             fprintf(stderr, "contradiction, line %d\n", lno);
  281. #endif
  282.             continue;
  283.         }
  284.  
  285.         /* Then, apply the actual values. */
  286.         if (ifdefs && (ifdefs & is_defined) != ifdefs) {
  287. #if 0
  288.             fprintf(stderr, "ifdef failed, line %d\n", lno);
  289. #endif
  290.             continue;
  291.         }
  292.         if (ifndefs && (ifndefs & is_undefined) != ifndefs) {
  293. #if 0
  294.             fprintf(stderr, "ifndef failed, line %d\n", lno);
  295. #endif
  296.             continue;
  297.         }
  298.  
  299.         /* Add array offsets. */
  300.         if (!(ifdefs & MODE_COLOR) && !(ifndefs & MODE_COLOR)) {
  301.             if (n_color >= ARRSZ || n_mono >= ARRSZ) {
  302.                 fprintf(stderr,
  303.                     "%s, line %d: Buffer overflow\n",
  304.                     filename, lno);
  305.                 exit(1);
  306.             }
  307.             a_color[n_color] = cc;
  308.             l_color[n_color++] = lno;
  309.             a_mono[n_mono] = cc;
  310.             l_mono[n_mono++] = lno;
  311.         } else if (ifdefs & MODE_COLOR) {
  312.             if (n_color >= ARRSZ) {
  313.                 fprintf(stderr,
  314.                     "%s, line %d: Buffer overflow\n",
  315.                     filename, lno);
  316.                 exit(1);
  317.             }
  318.             a_color[n_color] = cc;
  319.             l_color[n_color++] = lno;
  320.         } else {
  321.             if (n_mono >= ARRSZ) {
  322.                 fprintf(stderr,
  323.                     "%s, line %d: Buffer overflow\n",
  324.                     filename, lno);
  325.                 exit(1);
  326.             }
  327.             a_mono[n_mono] = cc;
  328.             l_mono[n_mono++] = lno;
  329.         }
  330.  
  331.         /* Emit the text. */
  332.         emit_text:
  333.         continued = 0;
  334.         white = 0;
  335.         while ((c = *s++) != '\0') {
  336.             if (c == ' ' || c == '\t')
  337.                 white++;
  338.             else if (white) {
  339.                 emit(t, ' ');
  340.                 cc++;
  341.                 white = 0;
  342.             }
  343.             switch (c) {
  344.                 case ' ':
  345.                 case '\t':
  346.                 break;
  347.                 case '#':
  348.                 emit(t, '\\');
  349.                 emit(t, '#');
  350.                 cc += 2;
  351.                 break;
  352.                 case '\\':
  353.                 if (*s == '\0') {
  354.                     continued = 1;
  355.                     break;
  356.                 }
  357.                 /* else fall through */
  358.                 default:
  359.                 emit(t, c);
  360.                 cc++;
  361.                 break;
  362.             }
  363.         }
  364.         if (white) {
  365.             emit(t, ' ');
  366.             cc++;
  367.             white = 0;
  368.         }
  369.         if (!continued) {
  370.             emit(t, 0);
  371.             cc++;
  372.         }
  373.     }
  374.     if (ssp) {
  375.         fprintf(stderr, "%d missing #endif(s) in %s\n", ssp, filename);
  376.         fprintf(stderr, "last #ifdef was at line %u\n", ss[ssp-1].lno);
  377.         exit(1);
  378.     }
  379.     fprintf(t, "};\n\n");
  380.  
  381.     /* Emit the fallback arrays themselves. */
  382.     fprintf(t, "String color_fallbacks[%u] = {\n", n_color + 1);
  383.     for (i = 0; i < n_color; i++) {
  384.         fprintf(t, "\t(String)&fsd[%u], /* line %u */\n", a_color[i],
  385.             l_color[i]);
  386.     }
  387.     fprintf(t, "\t(String)NULL\n};\n\n");
  388.     fprintf(t, "String mono_fallbacks[%u] = {\n", n_mono + 1);
  389.     for (i = 0; i < n_mono; i++) {
  390.         fprintf(t, "\t(String)&fsd[%u], /* line %u */\n", a_mono[i],
  391.             l_mono[i]);
  392.     }
  393.     fprintf(t, "\t(String)NULL\n};\n\n");
  394.  
  395.     /* Emit some test code. */
  396.     fprintf(t, "%s", "#if defined(DEBUG) /*[*/\n\
  397. main()\n\
  398. {\n\
  399.     int i;\n\
  400. \n\
  401.     for (i = 0; color_fallbacks[i]; i++)\n\
  402.         fprintf(t, \"color %d: %s\\n\", i, color_fallbacks[i]);\n\
  403.     for (i = 0; mono_fallbacks[i]; i++)\n\
  404.         fprintf(t, \"mono %d: %s\\n\", i, mono_fallbacks[i]);\n\
  405.     exit(0);\n\
  406. }\n");
  407.     fprintf(t, "#endif /*]*/\n\n");
  408.     fprintf(t, "#endif /*]*/\n");
  409.  
  410.     /* Open the output file. */
  411.     if (argc == 3) {
  412.         o = fopen(argv[2], "w");
  413.         if (o == NULL) {
  414.             perror(argv[2]);
  415.             exit(1);
  416.         }
  417.     } else
  418.         o = stdout;
  419.  
  420.     /* Copy tmp to output. */
  421.     rewind(t);
  422.     while (fgets(buf, sizeof(buf), t) != NULL) {
  423.         fprintf(o, "%s", buf);
  424.     }
  425.     if (o != stdout)
  426.         fclose(o);
  427.     fclose(t);
  428.  
  429.     return 0;
  430. }
  431.  
  432. int n_out = 0;
  433.  
  434. void
  435. emit(FILE *t, char c)
  436. {
  437.     if (n_out >= 19) {
  438.         fprintf(t, "\n");
  439.         n_out = 0;
  440.     }
  441.     fprintf(t, "%3d,", (unsigned char)c);
  442.     n_out++;
  443. }
  444.